/*
 * Copyright 2010 Christoph Widulle (christoph.widulle@googlemail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */



package com.android1.amarena2d.actions;

import com.android1.amarena2d.actions.base.Action;
import com.android1.amarena2d.commons.collections.FixedSizeMap;
import com.android1.amarena2d.commons.collections.FixedSizePool;
import com.android1.amarena2d.engine.AmarenaEngine;
import com.android1.amarena2d.engine.EngineObject;


//currently unused
public class ActionPool extends EngineObject {

    public static final String LOG_TAG = "ActionPool";
    private FixedSizePool<Action> lastActionPool;
    private Class<? extends Action> lastActionClass;

    private FixedSizeMap<Class<? extends Action>, FixedSizePool<Action>> pool = new FixedSizeMap<Class<? extends Action>, FixedSizePool<Action>>(40);

    public boolean isPooled(final Class<? extends Action> actionClass) {
        if (pool.size() == 0)
            return false;
        FixedSizePool<Action> actions = pool.get(actionClass);
        if (actions != null) {
            lastActionPool = actions;
            lastActionClass = actionClass;
            return true;
        } else {
            return false;
        }
    }

    public <T extends Action> T acquire(final Class<T> actionClass) {
        FixedSizePool<Action> actions;
        if (lastActionClass != null && lastActionClass == actionClass) {
            actions = lastActionPool;
        } else {
            actions = pool.get(actionClass);
        }
        if (actions != null) {
            return actionClass.cast(actions.acquire());
        }
        if (AmarenaEngine.DEBUG)
            engine.log(LOG_TAG, "Pool for " + actionClass.getCanonicalName() + " is exhausted.");
        return null;
    }

    @SuppressWarnings("unchecked")
    public <T extends Action> boolean createPool(Class<T> actionClass, int size, final InstanceCreator<T> instanceCreator) {
        if (pool.containsKey(actionClass)) {
            if (AmarenaEngine.DEBUG)
                engine.log(LOG_TAG, "Pool for " + instanceCreator.getClass() + " has already been created.");
            return true;
        } else {
            FixedSizePool<T> actionPool = new FixedSizePool<T>(size) {
                @Override
                protected T newElement() {
                    return instanceCreator.newInstance();
                }
            };
            pool.put(actionClass, (FixedSizePool<Action>) actionPool);
            return true;
        }
    }

    public void release(final Action poolable) {
        FixedSizePool<Action> actionPool = pool.get(poolable.getClass());
        if (actionPool != null) {
            actionPool.release(poolable);
        }

    }

    public static interface InstanceCreator<T extends Action> {
        public T newInstance();
    }


}
